/*
 *所有关于devicedetail类的业务代码应在此处编写
*可使用repository.调用常用方法，获取EF/Dapper等信息
*如果需要事务请使用repository.DbContextBeginTransaction
*也可使用DBServerProvider.手动获取数据库相关信息
*用户信息、权限、角色等使用UserContext.Current操作
*devicedetailService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter
*/
using VOL.Core.BaseProvider;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
using System.Linq;
using VOL.Core.Utilities;
using System.Linq.Expressions;
using VOL.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using VOL.RadarDevice.IRepositories;
using System.Text;
using VOL.Entity.DomainModels.Devices.Dto;
using Newtonsoft.Json;
using VOL.Core.Configuration;
using VOL.Core.ManageUser;
using static System.Net.WebRequestMethods;
using VOL.Core.DbContext;
using VOL.Entity.DomainModels.Devices.MongoDbModels;
using Microsoft.Extensions.Options;

namespace VOL.RadarDevice.Services
{
    public partial class devicedetailService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly IdevicedetailRepository _repository;//访问数据库
        private readonly IdeviceShareRepository _repositorySharp;//访问数据库
        private readonly MongoDbContext _mongoDbContext;

        [ActivatorUtilitiesConstructor]
        public devicedetailService(
            MongoDbContext mongoDbContext,
            IdevicedetailRepository dbRepository,
            IdeviceShareRepository repositorySharp,
            IHttpContextAccessor httpContextAccessor
            )
        : base(dbRepository)
        {
            _httpContextAccessor = httpContextAccessor;
            _repository = dbRepository;
            _repositorySharp = repositorySharp;
            _mongoDbContext = mongoDbContext;
            //多租户会用到这init代码，其他情况可以不用
            //base.Init(dbRepository);
        }
        /// <summary>
        /// 列表查询
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public override PageGridData<devicedetail> GetPageData(PageDataOptions options)
        {
            var deviceNo = "";
            int? factorySettings = null;

            var listWhere = JsonConvert.DeserializeObject<List<OptionWheres>>(options.Wheres);
            foreach (var item in listWhere)
            {
                if (item.name == "deviceNo")
                    deviceNo = item.value;
                else if (item.name == "factorySettings" && !string.IsNullOrWhiteSpace(item.value))
                    factorySettings = int.Parse(item.value);
            }

            int pageSize = options.Rows; // 每页显示的数量
            int pageIndex = options.Page; // 当前页码
            string sort = options.Sort;

            var querys = repository.FindAsIQueryable(r => 1 == 1).WhereIF(!string.IsNullOrWhiteSpace(deviceNo), d => d.deviceNo.Contains(deviceNo))
                .WhereIF(factorySettings != null, d => d.factorySettings == factorySettings);

            var allowIds = AppSetting.QueryAllDeviceUserIds;
            if (!string.IsNullOrWhiteSpace(allowIds))
            {
                var userId = UserContext.Current.UserId;
                var strIds = allowIds.Split(',');
                var ids = Array.ConvertAll(strIds, int.Parse);
                if (!ids.Contains(userId))
                {
                    var sharpModels = _repositorySharp.FindAsIQueryable(r => 1 == 1).ToList();
                    List<deviceShare> shares = new List<deviceShare>();
                    foreach (var sharpModel in sharpModels)
                    {
                        var userIds = sharpModel.shareUserIds.Split(",");
                        if (userIds.Contains(userId.ToString()))
                        {
                            shares.Add(sharpModel);
                        }
                    }
                    var deviceIdList = shares.Select(r => r.deviceId).ToList();
                    querys = querys.Where(d => d.CreateID == userId || deviceIdList.Contains(d.device_id));
                }
            }
            var dtos = querys;
            if (options.Order == "desc")
                dtos = querys.OrderByDescending(d => d.updateTime).OrderByDescending(d => d.deviceNo).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            else
                dtos = querys.OrderBy(d => d.updateTime).OrderBy(d => d.deviceNo).Skip((pageIndex - 1) * pageSize).Take(pageSize);

            PageGridData<devicedetail> pageGridData = new PageGridData<devicedetail>();
            var models = dtos.ToList();

            pageGridData.rows = models;
            pageGridData.total = querys.ToList().Count;

            GetPageDataOnExecuted?.Invoke(pageGridData);
            return pageGridData;
        }
        /// <summary>
        /// 导出处理
        /// </summary>
        /// <param name="pageData"></param>
        /// <returns></returns>
        public override WebResponseContent Export(PageDataOptions pageData)
        {
            var deviceNo = "";
            int? factorySettings = null;

            var listWhere = JsonConvert.DeserializeObject<List<OptionWheres>>(pageData.Wheres);
            foreach (var item in listWhere)
            {
                if (item.name == "deviceNo")
                    deviceNo = item.value;
                else if (item.name == "factorySettings" && !string.IsNullOrWhiteSpace(item.value))
                    factorySettings = int.Parse(item.value);
            }

            var querys = repository.FindAsIQueryable(r => 1 == 1).WhereIF(!string.IsNullOrWhiteSpace(deviceNo), d => d.deviceNo.Contains(deviceNo))
                .WhereIF(factorySettings != null, d => d.factorySettings == factorySettings);

            var allowIds = AppSetting.QueryAllDeviceUserIds;
            if (!string.IsNullOrWhiteSpace(allowIds))
            {
                var userId = UserContext.Current.UserId;
                var strIds = allowIds.Split(',');
                var ids = Array.ConvertAll(strIds, int.Parse);
                if (!ids.Contains(userId))
                {
                    var sharpModels = _repositorySharp.FindAsIQueryable(r => 1 == 1).ToList();
                    List<deviceShare> shares = new List<deviceShare>();
                    foreach (var sharpModel in sharpModels)
                    {
                        var userIds = sharpModel.shareUserIds.Split(",");
                        if (userIds.Contains(userId.ToString()))
                        {
                            shares.Add(sharpModel);
                        }
                    }
                    var deviceIdList = shares.Select(r => r.deviceId).ToList();
                    querys = querys.Where(d => d.CreateID == userId || deviceIdList.Contains(d.device_id));
                }
            }
            var dtos = querys;
            if (pageData.Order == "asc")
                dtos = querys.OrderBy(d => d.updateTime).OrderBy(d => d.deviceNo);
            else
                dtos = querys.OrderByDescending(d => d.updateTime).OrderByDescending(d => d.deviceNo);
            var models = dtos.ToList();

            return base.MyExport(models);
        }
        /// <summary>
        /// 下发设备查询帧
        /// </summary>
        /// <param name="deviceNo">设备编号</param>
        /// <returns></returns>
        public async Task<WebResponseContent> SendDeviceQueryFrame(string deviceNo)
        {
            if (string.IsNullOrWhiteSpace(deviceNo))
            {
                return new WebResponseContent().Error("设备编号不能为空！");
            }
            var userId = UserContext.Current.UserId;
            var user = UserContext.Current.GetUserInfo(userId);
            var url = $"{AppSetting.TcpServiceApiUrl}Radar/api/QueryDeviceInfo?deviceNo={deviceNo}&userId={userId}&name={user.UserTrueName}";
            var resStr = await HttpGet(url);
            if (string.IsNullOrEmpty(resStr))
            {
                return new WebResponseContent().Error("指令添加异常");
            }
            var res = JsonConvert.DeserializeObject<ApiResult>(resStr);
            if (res.success)
            {
                return new WebResponseContent().OK("指令添加成功");
            }
            return new WebResponseContent().Error(res.message);
        }
        /// <summary>
        /// 发送设备设置指令
        /// </summary>
        /// <param name="saveDataModel"></param>
        /// <returns></returns>
        public override WebResponseContent Update(SaveModel saveDataModel)
        {
            if (saveDataModel.MainData.DicKeyIsNullOrEmpty("deviceNo"))
            {
                return new WebResponseContent().Error("设备编号不能为空！");
            }
            var factorySettings = saveDataModel.MainData["factorySettings"].GetInt();
            DeviceDetailDto dto = new DeviceDetailDto()
            {
                deviceNo = saveDataModel.MainData["deviceNo"].ToString(),
                factorySettings= factorySettings,
                detectiontime = saveDataModel.MainData["detectiontime"].GetInt(),
                baudRate = saveDataModel.MainData["baudRate"].GetInt(),
                sensitivity = saveDataModel.MainData["sensitivity"].GetInt(),
                beamWidth = saveDataModel.MainData["beamWidth"].GetInt(),
                normalThreshold = saveDataModel.MainData["normalThreshold"].GetDecimal(),
                rangeThreshold = saveDataModel.MainData["rangeThreshold"].GetDecimal(),
                averageValue = saveDataModel.MainData["averageValue"].GetInt(),
                biasValue = saveDataModel.MainData["biasValue"].GetInt(),
                highValue = saveDataModel.MainData["highValue"].GetInt(),
                dacOutputLowest = saveDataModel.MainData["dacOutputLowest"].GetInt(),
                dacOutputMax= saveDataModel.MainData["dacOutputMax"].GetInt(),
                trackingEnabled = sbyte.Parse(saveDataModel.MainData["trackingEnabled"].ToString()),
                targetFilter = saveDataModel.MainData["targetFilter"].GetInt(),
                sensorTemperature = saveDataModel.MainData["sensorTemperature"].GetDecimal(),
                alarmUpperLimit = saveDataModel.MainData["alarmUpperLimit"].GetInt(),
                alarmLowerLimit = saveDataModel.MainData["alarmLowerLimit"].GetInt(),
                startDistance = saveDataModel.MainData["startDistance"].GetInt(),
                endDistance = saveDataModel.MainData["endDistance"].GetInt(),
                surgeFiltration = saveDataModel.MainData["surgeFiltration"].GetInt()
            };

            var userId = UserContext.Current.UserId;
            var user = UserContext.Current.GetUserInfo(userId);
            dto.Id = userId;
            dto.Name = user.UserTrueName;

            var jsonStr = JsonConvert.SerializeObject(dto);

            var url = AppSetting.TcpServiceApiUrl + $"Radar/api/SetDeviceInfo";
            var resStr = HttpPost(url, jsonStr).Result;
            if (string.IsNullOrEmpty(resStr))
            {
                return new WebResponseContent().Error("指令添加异常");
            }
            var res = JsonConvert.DeserializeObject<ApiResult>(resStr);
            if (res.success)
            {
                return new WebResponseContent().OK("指令添加成功");
            }
            return new WebResponseContent().Error(res.message);
        }

        #region HTTP请求
        /// <summary>
        /// http Get请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <returns></returns>
        public async Task<string> HttpGet(string url)
        {
            string resStr = "";
            using (HttpClient client = new HttpClient())
            {
                try
                {
                    // 发送GET请求
                    HttpResponseMessage response = await client.GetAsync(url);
                    // 确保请求成功
                    response.EnsureSuccessStatusCode();

                    // 读取响应内容作为字符串
                    resStr = await response.Content.ReadAsStringAsync();
                }
                catch (HttpRequestException e)
                {
                    Console.WriteLine("Message :{0} ", e.Message);
                }
            }
            return resStr;
        }
        /// <summary>
        /// Http Post请求(参数Json)
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="param">请求参数(json)</param>
        /// <returns></returns>
        public async Task<string> HttpPost(string url, string param)
        {
            string resStr = "";
            using (HttpClient client = new HttpClient())
            {
                try
                {
                    if (!string.IsNullOrEmpty(param))
                    {
                        // 将JSON字符串转换为HttpContent对象，并设置Content-Type为application/json
                        HttpContent content = new StringContent(param, Encoding.UTF8, "application/json");
                        // 发送POST请求
                        HttpResponseMessage response = await client.PostAsync(url, content);
                        // 确保请求成功
                        response.EnsureSuccessStatusCode();
                        resStr = await response.Content.ReadAsStringAsync();
                    }
                    else
                    {
                        HttpResponseMessage response = await client.PostAsync(url, null);
                        // 确保请求成功
                        response.EnsureSuccessStatusCode();
                        // 读取响应内容
                        resStr = await response.Content.ReadAsStringAsync();
                    }
                }
                catch (HttpRequestException e)
                {
                    Console.WriteLine("\nException Caught!");
                    Console.WriteLine("Message :{0} ", e.Message);
                }
            }
            return resStr;
        }
        #endregion HTTP请求
    }
}
